﻿using System;
using System.Collections.Generic;
using System.IO;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;

namespace FixChestsBug
{
    [ApiVersion(2, 1)]
    public class Main : TerrariaPlugin
    {
        public Main(Terraria.Main game) : base(game)
        {
        }

        public override string Name => "FixChestBug";

        public override Version Version => new Version(0,2);

        public override string Author => "豆沙";

        public override string Description => "尝试修复俩个箱子刷物品的BUG";
        public static List<ChestPlayer> players = new List<ChestPlayer>();

        public override void Initialize()
        {
            GetDataHandlers.ChestOpen += OnOpen;   
            ServerApi.Hooks.ServerJoin.Register(this,OnJoin);
            ServerApi.Hooks.ServerLeave.Register(this,OnLeave);
            ServerApi.Hooks.NetGetData.Register(this,OnGetData);
            ServerApi.Hooks.ServerChat.Register(this,OnChat);
        }

        private void OnChat(ServerChatEventArgs args)
        {
            var tsplr = new TSPlayer(args.Who);
            var cplr = players.Find(p=>p.Name==tsplr.Name);
            if (args.Text.ToLower()=="cancel")
            {
                cplr.Status = Status.Comon;
                tsplr.SendInfoMessage("已解开");
                args.Handled = true;
            }
        }

        private void OnLeave(LeaveEventArgs args)
        {
            var plr = new TSPlayer(args.Who);
            
            players.Remove(players.Find(p=>p.Name==plr.Name));
        }

        private void OnJoin(JoinEventArgs args)
        {
            var plr = new TSPlayer(args.Who);
            if (!players.Exists(p=>p.Name==plr.Name))
            {
                players.Add(new ChestPlayer(Status.Comon,plr.Name));
            }
        }

        private void OnGetData(GetDataEventArgs args)
        {
           
                switch (args.MsgID)
                {
                    case PacketTypes.ChestOpen:
                    var tsplr = TShock.Players[args.Msg.whoAmI];
                    var cplr = players.Find(p=>p.Name==tsplr.Name);
                    using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                    {
                        var chestID = reader.ReadInt16();
                        if (chestID==-1&&cplr.Status==Status.OpenChest)
                        {
                            cplr.Status = Status.Comon;
                        }
                        if (chestID==-2&&cplr.Status==Status.Comon)
                        {
                            cplr.Status = Status.OpenPiggyBank;
                        }
                        if (chestID==-2&&(cplr.Status==Status.OpenChest||cplr.Status==Status.OpenSafe))
                        {
                            tsplr.KillPlayer();
                            tsplr.SendErrorMessage("请关闭箱子或保险箱后打开");
                            tsplr.SendErrorMessage("如果打开不了输入cancel解开");
                            tsplr.TPlayer.inventory[58].netID = 0;
                            NetMessage.SendData((int)PacketTypes.PlayerSlot, -1, -1, tsplr.TPlayer.inventory[58].Name, tsplr.Index, 58, tsplr.TPlayer.inventory[58].prefix);
                            NetMessage.SendData((int)PacketTypes.PlayerSlot, tsplr.Index, -1, tsplr.TPlayer.inventory[58].Name, tsplr.Index, 58, tsplr.TPlayer.inventory[58].prefix);
                            tsplr.SendData(PacketTypes.ChestOpen, "", -2);
                            args.Handled = true;
                        }
                        if (chestID == -3 && cplr.Status == Status.Comon)
                        {
                            cplr.Status = Status.OpenSafe;
                        }
                        if (chestID == -3 && (cplr.Status == Status.OpenChest || cplr.Status == Status.OpenPiggyBank))
                        {
                            tsplr.KillPlayer();
                            tsplr.SendErrorMessage("请关闭箱子或猪猪罐后打开");
                            tsplr.SendErrorMessage("如果打开不了输入cancel解开");
                            tsplr.TPlayer.inventory[58].netID = 0;
                            NetMessage.SendData((int)PacketTypes.PlayerSlot,-1,-1, tsplr.TPlayer.inventory[58].Name, tsplr.Index,58,tsplr.TPlayer.inventory[58].prefix);
                            NetMessage.SendData((int)PacketTypes.PlayerSlot, tsplr.Index, -1, tsplr.TPlayer.inventory[58].Name, tsplr.Index, 58, tsplr.TPlayer.inventory[58].prefix);
                            tsplr.SendData(PacketTypes.ChestOpen, "", -3);                           
                            args.Handled = true;
                        }
                    }
                    break;
                }
  
        }
        private void OnOpen(object sender,GetDataHandlers.ChestOpenEventArgs args) {
            var plr = players.Find(p=>p.Name==args.Player.Name);
            switch (plr.Status)
            {
                case Status.OpenChest:
                    args.Handled = true;
                    args.Player.SendErrorMessage("请关闭现在这个箱子后打开另外一个箱子");
                    break;
                case Status.OpenPiggyBank:
                    args.Player.SendErrorMessage("请输入cancel后打开箱子");
                    args.Handled = true;
                    break;
                case Status.OpenSafe:
                    args.Player.SendErrorMessage("请输入cancel后打开箱子");
                    args.Handled = true;
                    break;
                case Status.Comon:
                    plr.Status = Status.OpenChest;
                    break;
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                GetDataHandlers.ChestOpen -= OnOpen;
                ServerApi.Hooks.ServerJoin.Deregister(this, OnJoin);
                ServerApi.Hooks.ServerLeave.Deregister(this, OnLeave);
                ServerApi.Hooks.NetGetData.Deregister(this, OnGetData);
                ServerApi.Hooks.ServerChat.Deregister(this, OnChat);
            }
            base.Dispose(disposing);
        }
    }
}
